package com.hpe.aruba.CPPM;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;

import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.textfield.TextInputLayout;
import com.hpe.aruba.CPPM.interfaces.CreateDeviceInterface;
import com.hpe.aruba.CPPM.interfaces.JsonInterface;
import com.hpe.aruba.CPPM.objects.Device;
import com.hpe.aruba.CPPM.objects.Role;
import com.hpe.aruba.CPPM.utils.ClearpassUtils;
import com.hpe.aruba.CPPM.utils.MacAdressMatcher;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;

public class NewDeviceActivity extends AppCompatActivity implements CreateDeviceInterface, JsonInterface {

    /*
    * Activity to create a new device.
    * Required: mac, vendor, role ID
    * TODO:
    *  - error handling, eg utils.MacAdressMatcher
    *  - add other useful fields
    *  DeviceCreate {
        create_time (string, optional): Time at which the account was created,
        current_state (string, optional) = ['active' or 'disabled' or 'expired' or 'pending']: Read-only property indicating the current state of the account,
        enabled (boolean, optional): Flag indicating if the account is enabled,
        expire_time (string, optional): Time at which the account will expire,
        mac (string): MAC address of the device,
        notes (string, optional): Comments or notes stored with the account,
        role_id (integer): Role to assign to the account,
        role_name (string, optional): Name of the role assigned to the account,
        source (string, optional): Origin of the account,
        sponsor_name (string, optional): Name of the sponsor of the account,
        sponsor_profile (string, optional): Numeric operator profile ID for the account’s sponsor,
        sponsor_profile_name (string, optional): Name of the operator profile for the account’s sponsor,
        start_time (string, optional): Time at which the account will be enabled,
        visitor_name (string, optional): Name to display for the account,
        ... (string, optional): Additional properties (custom fields) may be stored with the account
      }
    * */



    private static final String DEVICES = "com.hpe.aruba.CPPM.DEVICES";
    private ArrayList<Device> macs;
    Device newDevice = new Device();
    final private String TAG = "CLEARPASS";
    ClearpassUtils clearpassUtils;
    RequestQueue queue;
    ProgressDialog submittingDialog;


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState); /*this might be wrong (why save this instance?)*/
        setContentView(R.layout.activity_new_device);

        /*for adding a device*/
        queue = Volley.newRequestQueue(this);
        clearpassUtils = new ClearpassUtils(queue);

        /*to passthrough to scanner*/
        Intent intent = getIntent();
        macs = intent.getParcelableArrayListExtra(DEVICES);
        /*gets guest roles and passes it to apply to set up the spinner*/
        clearpassUtils.getGuestRoles(this);

    }

    public void apply(JSONObject rolesJson) {
        ArrayList<Role> roles = new ArrayList<>();
        try {
            roles = (ArrayList<Role>) rolesJson.get("roles");
        } catch (JSONException e) {
            Log.e(TAG, e.getMessage());
        }

        /*set up spinner*/
        Spinner spinner = findViewById(R.id.new_role);
        if (roles != null) {
            ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, roles);
            adapter.setDropDownViewResource(android.R.layout
                    .simple_spinner_dropdown_item);
            spinner.setAdapter(adapter);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_confirm, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle item selection
        switch (item.getItemId()) {
            case R.id.confirm:
                onSubmit();
                return true;
            default:
                setResult(RESULT_CANCELED);
                finish();
                return true;
        }
    }

    public void scanMac(View view) {
        Toast.makeText(this, "To be fixed, broken.",
                Toast.LENGTH_SHORT).show();
        Intent intent = new Intent(this, MultiTrackerActivity.class);
        intent.putParcelableArrayListExtra(DEVICES, macs); /*add list of macs to intent*/
        startActivity(intent);
    }


    public void onSubmit() {
        /*hide keyboard (also important so snackbar is visible onerror)*/
        InputMethodManager inputManager = (InputMethodManager)
                getSystemService(Context.INPUT_METHOD_SERVICE);

        inputManager.hideSoftInputFromWindow((null == getCurrentFocus()) ?
                /*null if it is already hidden, avoids exception*/
                null : getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);

        /*show loading popup*/
        submittingDialog = new ProgressDialog(NewDeviceActivity.this,
            R.style.AppTheme_Dark_Dialog);
        submittingDialog.setIndeterminate(true);
        submittingDialog.setMessage(getResources().getText(R.string.submitting));
        submittingDialog.show();

        /*get inputs*/
        EditText macField = (EditText) findViewById(R.id.new_mac);
        String mac = macField.getText().toString().toUpperCase(); /*to upper case to ease input*/
        MacAdressMatcher macAdressMatcher = new MacAdressMatcher();
        if (!macAdressMatcher.isMac(mac, false)) { /*malformed mac handling */
            /*get box around MAC field*/
            TextInputLayout macFieldLayout = (TextInputLayout) findViewById(R.id.new_mac_layout);
            macFieldLayout.setError(getResources().getText(R.string.error_bad_mac));
            return;
        }

        EditText vendorField = (EditText) findViewById(R.id.new_vendor);
        String vendor = vendorField.getText().toString();
        EditText notesField = (EditText) findViewById(R.id.new_notes);
        String notes = notesField.getText().toString();
        Log.d("nts", notes);
        Spinner roleField = (Spinner) findViewById(R.id.new_role);
        Role role = (Role) roleField.getSelectedItem();

        newDevice.setMac(mac); /*req*/
        newDevice.setVendor(vendor);
        newDevice.setNotes(notes);
        newDevice.setRole_name(role.getName());
        newDevice.setRole_id(role.getId()); /*req*/
        newDevice.setImported(false); /*not imported (so not out of clearpass)*/
        newDevice.setCreate_time("" + System.currentTimeMillis());
        /*macs.add(newDevice);*/

        clearpassUtils.createDevice(newDevice, this);
    }


    public void onSuccess() {
        /*pass it back*/
        Intent intent = new Intent();
        intent.putParcelableArrayListExtra(DEVICES, macs);
        setResult(RESULT_OK, intent);
        /*close loading dialog*/
        submittingDialog.dismiss();
        finish();
    }

    public void onError(String reason) {
        Log.e(TAG, "Error submitting: " + (reason.equals("") ? "unknown": reason));
        CharSequence error;
        TextInputLayout macFieldLayout = (TextInputLayout) findViewById(R.id.new_mac_layout);
        macFieldLayout.setError(null); /*clear error*/
        switch (reason) {
            case "422":
                /*TODO: differentiate between auth and already exists*/
                error = getResources().getText(R.string.error_auth_or_already_exists);
                break;
            case "Volley":
                error = getResources().getText(R.string.error_volley);
                break;
            case "parsing":
                error = getResources().getText(R.string.error_parsing);
                break;
            default:
                error = getResources().getText(R.string.error_unknown);
        }
        View view = findViewById(R.id.new_device_layout);
        submittingDialog.dismiss(); /*close loading dialog*/
        Snackbar.make(view, error,Snackbar.LENGTH_LONG)
                .show();
    }
}
